﻿using System;
using System.Collections.Generic;
using Fabrication.Exceptions;
using NUnit.Framework;

namespace Fabrication.Tests
{
    [TestFixture]
    public class typed_property_key
    {
        [Test]
        public void should_be_equal_if_name_and_type_match()
        {
            var key1 = new TypedPropertyKey(typeof(string), "name");
            var key2 = new TypedPropertyKey(typeof(string), "name");

            Assert.That(key1, Is.EqualTo(key2));
        }

        [Test]
        public void should_be_equal_if_name_only_differs_by_case()
        {
            var key1 = new TypedPropertyKey(typeof(string), "name");
            var key2 = new TypedPropertyKey(typeof(string), "Name");

            Assert.That(key1, Is.EqualTo(key2));
        }

        [Test]
        public void should_be_equal_if_same_instance()
        {
            var key1 = new TypedPropertyKey(typeof(string), "name");
            var key2 = key1;

            Assert.That(key1, Is.EqualTo(key2));
        }

        [Test]
        public void should_not_be_equal_if_name_does_not_match()
        {
            var key1 = new TypedPropertyKey(typeof(string), "name");
            var key2 = new TypedPropertyKey(typeof(string), "name2");

            Assert.That(key1, Is.Not.EqualTo(key2));
        }

        [Test]
        public void should_not_be_equal_if_type_does_not_match()
        {
            var key1 = new TypedPropertyKey(typeof(string), "name");
            var key2 = new TypedPropertyKey(typeof(int), "name");

            Assert.That(key1, Is.Not.EqualTo(key2));
        }

        [Test]
        public void should_not_be_equal_if_compared_to_other_type()
        {
            var key1 = new TypedPropertyKey(typeof(string), "name");
            var key2 = new KeyValuePair<Type, string>(typeof(string), "name");

            Assert.That(key1.Equals(key2), Is.False);
        }

        [Test]
        public void should_not_be_equal_if_compared_to_null()
        {
            var key1 = new TypedPropertyKey(typeof(string), "name");

            Assert.That(key1.Equals(null), Is.False);
        }

        [Test]
        public void should_fail_if_property_type_is_null()
        {
            Assert.Throws<TypedPropertyException>(() => new TypedPropertyKey(null, "name"));
        }

        [Test]
        public void should_fail_if_property_name_is_invalid()
        {
            Assert.Throws<TypedPropertyException>(() => new TypedPropertyKey(typeof(string), null));
            Assert.Throws<TypedPropertyException>(() => new TypedPropertyKey(typeof(string), ""));
            Assert.Throws<TypedPropertyException>(() => new TypedPropertyKey(typeof(string), " "));
        }
    }
}
